package models.weixin;

import jodd.bean.BeanCopy;
import models.constants.DeletedStatus;
import models.constants.Gender;
import models.enums.IdentityType;
import models.enums.UserFromType;
import models.merchant.Merchant;
import order.OrderItem;
import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;
import play.db.jpa.Model;
import play.modules.paginate.JPAExtPaginator;
import shopcart.ShopCart;
import util.xsql.XsqlBuilder;
import javax.persistence.*;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by shancheng on 16-6-17.
 */
@Entity
@Table(name = "power_web_users")
public class WebUser extends Model {

    private static final long serialVersionUID = 289109934185631L;
    public static final String WXMP_CACHEKEY  = "WxMpUser2_";

    /**
     * 微信用户名，fromUserName.
     * TODO: 加上索引.
     */
    @Column(name = "openId", length = 50)
    public String openId;


    /**
     * 用户属于哪一个微信号
     */
    @JoinColumn(name = "weixin_data")
    @ManyToOne
    public WeixinData weixinData;


    /**
     * 逻辑删除,0:未删除，1:已删除
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "from_type")
    public UserFromType fromType = UserFromType.WEIXIN;


    /**
     * 用户身份  普通用户  商户
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "identity_type")
    public IdentityType identityType = IdentityType.USER;


    /**
     * 认证授权码 本人/本商户 授权码 具有唯一性
     */
    @Column(name = "identity_code")
    public String identityCode;

    /**
     * 介绍人授权码  跟 identityCode 对应
     */
    @Column(name = "introduce_code")
    public String introduceCode;

    /**
     * 微信确认身份用
     */
    @Column(name = "uuid")
    public String uuid;


    /**
     * 是否订阅.
     * 用户是否订阅该公众号标识，值为0时，代表此用户没有关注该公众号，拉取不到其余信息。
     * 可考虑通过一个定时任务查询当前公众号的用户订阅状态.
     */
    @Column(name = "subcribed")
    public Boolean subcribed;

    /**
     * 用户的昵称
     */
    @Column(name = "nick_name", length = 50)
    public String nickName;


    @Enumerated(EnumType.STRING)
    @Column(name = "sex", length = 10)
    public Gender sex;

    /**
     * 用户语言
     */
    @Column(name = "user_lang", length = 20)
    public String language;


    @Column(name = "city", length = 20)
    public String city;


    /**
     * 领取卡券次数
     */
    @Column(name = "give_coupon_count")
    public Integer giveCouponCount = 0;


    @Column(name = "country", length = 20)
    public String country;


    /**
     * 是否第一次进入
     */
    @Column(name = "is_first")
    public Boolean isFirst;

    /**
     * 用户头像路径.
     * <p/>
     * 保存微信文件到本地.
     */
    @Column(name = "head_img_url", length = 200)
    public String headImgUrl;

    @Column(name = "phone")
    public String phone;

    @Column(name = "birthDay")
    public String birthDay;

    @Column(name = "sign")
    public String sign;

    /**
     * 用户注册时间.
     * 用户注册时间
     */
    @Column(name = "created_at")
    public Date createAt;

    /**
     * 逻辑删除,0:未删除，1:已删除
     */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "deleted")
    public DeletedStatus deleted = DeletedStatus.UN_DELETED;

    /**
     * 备注
     */
    @Column (name = "remark")
    public String remark;

    /**
     * 支付宝号
     */
    @Column(name = "alipay_id")
    public String alipayId;

    /**
     * 用户可提现金额
     */
    @Column(name = "withdrawals_amount")
    public Double withdrawalsAmount;

    @Transient
    public double sumPrice;

    @Transient
    public int itemCount;

    /**
     * 分页查询.
     */
    public static JPAExtPaginator<WebUser> findByCondition(Map<String, Object> conditionMap, String orderByExpress, int pageNumber, int pageSize) {
        StringBuilder xsqlBuilder = new StringBuilder("t.deleted=models.constants.DeletedStatus.UN_DELETED ")
                .append("/~ and t.phone = {phone} ~/")
                .append("/~ and t.merchant.id = {merchantId} ~/")
                .append("/~ and t.nickName like {nickName} ~/");

        XsqlBuilder.XsqlFilterResult result = new util.xsql.XsqlBuilder().generateHql(xsqlBuilder.toString(), conditionMap);
        JPAExtPaginator<WebUser> orderPage = new JPAExtPaginator<WebUser>("WebUser t", "t", WebUser.class,
                result.getXsql(), conditionMap).orderBy(orderByExpress);
//        orderPage.setPageNumber(pageNumber);
//        orderPage.setPageSize(pageSize);
//        orderPage.setBoundaryControlsEnabled(false);
        return orderPage;
    }

    /**
     * 按weixinUser值更新指定ID的WeixinUser.
     */
    public static void update(Long id, WebUser weixinUser) {
        WebUser oldWeixinUser = WebUser.findById(id);
        BeanCopy.beans(weixinUser, oldWeixinUser).ignoreNulls(true).copy();
        oldWeixinUser.save();
    }

    /**
     * 删除指定ID的WeixinMenu
     */
    public static void delete(Long id) {
        WebUser weixinUser = WebUser.findById(id);
        weixinUser.deleted = DeletedStatus.DELETED;
        weixinUser.save();
    }

    /**
     * 根据OpenId查询用户
     */
    public static WebUser findByOpenId(String openId) {
        return WebUser.find("openId = ?1 and deleted = ?2" , openId , DeletedStatus.UN_DELETED).first();
    }



    public static List<WebUser> findAvailable() {
        return WebUser.find("deleted = ?1" , DeletedStatus.UN_DELETED).fetch();
    }

    public Long shopCount() {
        return ShopCart.findShopCartSize(this );
    }

    /**
     * 根据授权码查询用户
     * @param identityCode
     * @return
     */
    public static WebUser findByIdentityCode(String identityCode) {
        return WebUser.find("identityCode = ?1 and deleted = ?2" , identityCode , DeletedStatus.UN_DELETED).first();
    }

    public static WebUser findByUserId(long id){
        return WebUser.find(" id = ?1 and deleted = ?2",id,DeletedStatus.UN_DELETED).first();
    }



    public static WebUser findByUUid(String uuid) {
        return WebUser.find("uuid = ?1 and deleted = ?2" , uuid , DeletedStatus.UN_DELETED).first();
    }
    public  static   List<WebUser> findBYWeiXinDataId(Long merchantId){
        Merchant merchant = Merchant.findByMerchantId(merchantId);
        return  WebUser.find("deleted = ?1 and weixinData.id = ?2",DeletedStatus.UN_DELETED, merchant.weixinData.id).fetch();
    }


    public static WebUser findByPhone(String phone) {
        return WebUser.find("phone = ?1 and deleted = ?2" , phone , DeletedStatus.UN_DELETED).first();
    }

    public static List<WebUser> loadByMerchant(long merchantId){
        return WebUser.find(" deleted = ?1 and merchant.id = ?2 " , DeletedStatus.UN_DELETED , merchantId).fetch();
    }

    public static List<WebUser> findUserByPhone(String phone) {
        return WebUser.find("phone = ?1 and deleted = ?2" , phone , DeletedStatus.UN_DELETED).fetch();
    }

    /**
     * 手机号是否被占用
     * @param phone
     * @return
     */
    public static WebUser findByPhoneOccupy(String phone,long webUserId) {
        return WebUser.find("phone = ?1 and deleted = ?2  and id != ?3 " , phone , DeletedStatus.UN_DELETED,webUserId).first();
    }

    public static List<WebUser> getListByWebUser(String nickName,String phone,Integer pageNum,Integer pageSize){
        StringBuilder sb = new StringBuilder(" select u.id id,u.nick_name nickName,u.phone phone,u.head_img_url headImgUrl,u.sex ,round(sum(oi.amount),2) sumPrice,count(oi.id) itemCount ");
        sb.append(" from power_web_users u  ");
        sb.append(" left JOIN orders o on o.web_user_id = u.id  ");
        sb.append(" left join order_items oi on o.id = oi.order_id  ");
        sb.append(" where u.deleted ='0' and o.status = 'PAID'  ");
       if( nickName != null && !nickName.equals("") ){
            sb.append(" and u.nick_name like '%").append(nickName).append("%'");
        }
        if(phone != null  &&  !phone.equals("")){
            sb.append(" and u.phone ='").append(phone).append("'");
        }
        sb.append(" GROUP BY u.id  ");
        sb.append(" order by sumPrice desc");
        if(pageNum != null){
            sb.append(" LIMIT ").append(pageNum).append(",").append(pageSize);
        }
        Query query = OrderItem.em().createNativeQuery(sb.toString());
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        List<WebUser> resulList = query.getResultList();
        return  resulList;
    }

    /**
     *  按时间统计新增顾客
     * @param beginDate
     * @param endDate
     * @return
     */
    public static List<WebUser> findYesterday(Date beginDate, Date endDate) {
        return WebUser.find(" deleted = ?1 and createAt between ?2 and ?3" , DeletedStatus.UN_DELETED ,beginDate,endDate ).fetch();
    }




}
